* modernize radius filter ...
and fix a memory leak when maxcount option discards wpts.
* radius loop safety.
* allow any Comparable with Waypoint/Route List sort.
* use static_cast instead of reinterpret_cast to
recover original type from void*.
if (waypointp->extra_data) {
ed = (extra_data*) waypointp->extra_data;
} else {
- ed = (extra_data*) xcalloc(1, sizeof(*ed));
+ ed = new extra_data;
ed->distance = BADVAL;
}
if (ed->distance == BADVAL || projectopt || ed->distance >= pos_dist) {
qPrintable(wp->shortname), ed->distance, wp->latitude, wp->longitude);
}
}
- xfree(ed);
+ delete ed;
}
}
if (global_opts.verbose_status > 0) {
#ifndef DEFS_H_INCLUDED_
#define DEFS_H_INCLUDED_
+#include <algorithm> // for sort, stable_sort
#include <cmath> // for M_PI
#include <cstdarg> // for va_list
#include <cstddef> // for NULL, nullptr_t, size_t
class WaypointList : private QList<Waypoint*>
{
public:
- using Compare = bool (*)(const Waypoint*, const Waypoint*);
-
void waypt_add(Waypoint* wpt); // a.k.a. append(), push_back()
void add_rte_waypt(int waypt_ct, Waypoint* wpt, bool synth, const QString& namepart, int number_digits);
// FIXME: Generally it is inefficient to use an element pointer or reference to define the element to be deleted, use iterator instead,
void copy(WaypointList** dst) const;
void restore(WaypointList* src);
void swap(WaypointList& other);
- void sort(Compare cmp);
+ template <typename Compare>
+ void sort(Compare cmp) {std::stable_sort(begin(), end(), cmp);}
template <typename T>
void waypt_disp_session(const session_t* se, T cb);
void waypt_backup(WaypointList** head_bak);
void waypt_restore(WaypointList* head_bak);
void waypt_swap(WaypointList& other);
-void waypt_sort(WaypointList::Compare cmp);
+template <typename Compare>
+void waypt_sort(Compare cmp)
+{
+ extern WaypointList* global_waypoint_list;
+
+ global_waypoint_list->sort(cmp);
+}
void waypt_add_url(Waypoint* wpt, const QString& link,
const QString& url_link_text);
void waypt_add_url(Waypoint* wpt, const QString& link,
class RouteList : private QList<route_head*>
{
public:
- using Compare = bool (*)(const route_head*, const route_head*);
-
int waypt_count() const;
void add_head(route_head* rte); // a.k.a. append(), push_back()
// FIXME: Generally it is inefficient to use an element pointer or reference to define the element to be deleted, use iterator instead,
void copy(RouteList** dst) const;
void restore(RouteList* src);
void swap(RouteList& other);
- void sort(Compare cmp);
+ template <typename Compare>
+ void sort(Compare cmp) {std::sort(begin(), end(), cmp);}
template <typename T1, typename T2, typename T3>
void disp_all(T1 rh, T2 rt, T3 wc);
template <typename T2, typename T3>
void route_backup(RouteList** head_bak);
void route_restore(RouteList* head_bak);
void route_swap(RouteList& other);
-void route_sort(RouteList::Compare cmp);
+template <typename Compare>
+void route_sort(Compare cmp)
+{
+ extern RouteList* global_route_list;
+
+ global_route_list->sort(cmp);
+}
void track_backup(RouteList** head_bak);
void track_restore(RouteList* head_bak);
void track_swap(RouteList& other);
-void track_sort(RouteList::Compare cmp);
+template <typename Compare>
+void track_sort(Compare cmp)
+{
+ extern RouteList* global_track_list;
+
+ global_track_list->sort(cmp);
+}
computed_trkdata track_recompute(const route_head* trk);
template <typename T>
*/
-#include <cstdlib> // for atof, atoi, qsort, strtod
+#include <cstdlib> // for atoi, strtod
#include <QtCore/QString> // for QString
-#include <QtCore/QtGlobal> // for foreach
+#include <QtCore/QtGlobal> // for qAsConst, QAddConst<>::Type, foreach
-#include "defs.h"
+#include "defs.h" // for Waypoint, waypt_del, route_add_head, route_add_wpt, route_head, waypt_add, waypt_count, xcalloc, xfree, kMilesPerKilometer
#include "radius.h"
#include "grtcirc.h" // for RAD, gcdist, radtomiles
+
#if FILTERS_ENABLED
double RadiusFilter::gc_distance(double lat1, double lon1, double lat2, double lon2)
{
- return gcdist(
- RAD(lat1),
- RAD(lon1),
- RAD(lat2),
- RAD(lon2)
- );
-}
-
-int RadiusFilter::dist_comp(const void* a, const void* b)
-{
- const Waypoint* x1 = *(Waypoint**)a;
- const Waypoint* x2 = *(Waypoint**)b;
- auto* x1e = (extra_data*) x1->extra_data;
- auto* x2e = (extra_data*) x2->extra_data;
-
- if (x1e->distance > x2e->distance) {
- return 1;
- }
- if (x1e->distance < x2e->distance) {
- return -1;
- }
- return 0;
-
+ return radtomiles(gcdist(RAD(lat1), RAD(lon1), RAD(lat2), RAD(lon2)));
}
void RadiusFilter::process()
{
- Waypoint** comp;
- int i, wc;
- route_head* rte_head = nullptr;
+ // waypt_del may modify container.
foreach (Waypoint* waypointp, *global_waypoint_list) {
- double dist = gc_distance(waypointp->latitude,
- waypointp->longitude,
- home_pos->latitude,
- home_pos->longitude);
-
- /* convert radians to float point statute miles */
- dist = radtomiles(dist);
+ double dist = gc_distance(waypointp->latitude, waypointp->longitude,
+ home_pos->latitude, home_pos->longitude);
if ((dist >= pos_dist) == (exclopt == nullptr)) {
waypt_del(waypointp);
continue;
}
- auto* ed = (extra_data*) xcalloc(1, sizeof(extra_data));
+ auto* ed = new extra_data;
ed->distance = dist;
waypointp->extra_data = ed;
}
- wc = waypt_count();
-
- comp = (Waypoint**) xcalloc(wc, sizeof(*comp));
-
- i = 0;
-
- /*
- * Create an array of remaining waypoints, popping them off the
- * master queue as we go. This gives us something reasonable
- * for qsort.
- */
-
- foreach (Waypoint* wp, *global_waypoint_list) {
- comp[i] = wp;
- waypt_del(wp);
- i++;
- }
-
- if (!nosort) {
- qsort(comp, wc, sizeof(Waypoint*), dist_comp);
+ if (nosort == nullptr) {
+ auto dist_comp_lambda = [](const Waypoint* a, const Waypoint* b)->bool {
+ const auto* aed = static_cast<const extra_data*>(a->extra_data);
+ const auto* bed = static_cast<const extra_data*>(b->extra_data);
+ return aed->distance < bed->distance;
+ };
+ waypt_sort(dist_comp_lambda);
}
- if (routename) {
+ route_head* rte_head = nullptr;
+ if (routename != nullptr) {
rte_head = new route_head;
rte_head->rte_name = routename;
route_add_head(rte_head);
}
/*
- * The comp array is now sorted by distance. As we run through it,
- * we push them back onto the master wp list, letting us pass them
- * on through in the modified order.
+ * Create an list of remaining waypoints.
+ * Delete them, add them to the global waypoint list, or add them
+ * to a new route.
*/
- for (i = 0; i < wc; i++) {
- Waypoint* wp = comp[i];
- xfree(wp->extra_data);
+ WaypointList comp;
+ waypt_swap(comp);
+
+ int i = 0;
+ for (Waypoint* wp : qAsConst(comp)) {
+ delete static_cast<extra_data*>(wp->extra_data);
wp->extra_data = nullptr;
- if (maxctarg && i >= maxct) {
- continue;
- }
- if (routename) {
- route_add_wpt(rte_head, wp);
+ if ((maxctarg != nullptr) && (i >= maxct)) {
+ delete wp;
} else {
- waypt_add(wp);
+ if (routename != nullptr) {
+ route_add_wpt(rte_head, wp);
+ } else {
+ waypt_add(wp);
+ }
}
+ ++i;
}
-
- xfree(comp);
}
void RadiusFilter::init()
{
- char* fm;
-
pos_dist = 0;
- if (distopt) {
+ if (distopt != nullptr) {
+ char* fm;
pos_dist = strtod(distopt, &fm);
if ((*fm == 'k') || (*fm == 'K')) {
}
}
- if (maxctarg) {
+ if (maxctarg != nullptr) {
maxct = atoi(maxctarg);
} else {
maxct = 0;
home_pos = new Waypoint;
- if (latopt) {
- home_pos->latitude = atof(latopt);
+ if (latopt != nullptr) {
+ home_pos->latitude = strtod(latopt, nullptr);
}
- if (lonopt) {
- home_pos->longitude = atof(lonopt);
+ if (lonopt != nullptr) {
+ home_pos->longitude = strtod(lonopt, nullptr);
}
}
};
double gc_distance(double lat1, double lon1, double lat2, double lon2);
- static int dist_comp(const void* a, const void* b);
};
#endif // FILTERS_ENABLED
35.97203, -87.13470, Mountain Bike Heaven by susy1313
+36.05750, -86.89200, GittyUp by JoGPS / Warner Parks
+36.08280, -86.86728, Inlighting by JoGPS / Warner Parks
global_route_list->swap(other);
}
-void
-route_sort(RouteList::Compare cmp)
-{
- global_route_list->sort(cmp);
-}
-
void
track_backup(RouteList** head_bak)
{
global_track_list->swap(other);
}
-void
-track_sort(RouteList::Compare cmp)
-{
- global_track_list->sort(cmp);
-}
-
/*
* This really makes more sense for tracks than routes.
* Run over all the trackpoints, computing heading (course), speed, and
*this = other;
other = tmp_list;
}
-
-void RouteList::sort(Compare cmp)
-{
- std::sort(begin(), end(), cmp);
-}
#
rm -f ${TMPDIR}/radius.csv
gpsbabel -i geo -f ${REFERENCE}/geocaching.loc \
- -x radius,lat=35.9720,lon=-87.1347,distance=14.7 \
+ -x radius,lat=35.9720,lon=-87.1347,distance=20.0,maxcount=3 \
-o csv -F ${TMPDIR}/radius.csv
compare ${TMPDIR}/radius.csv ${REFERENCE}
-
global_waypoint_list->swap(other);
}
-void
-waypt_sort(WaypointList::Compare cmp)
-{
- global_waypoint_list->sort(cmp);
-}
-
void
waypt_add_url(Waypoint* wpt, const QString& link, const QString& url_link_text)
{
*this = other;
other = tmp_list;
}
-
-void WaypointList::sort(Compare cmp)
-{
- std::stable_sort(begin(), end(), cmp);
-}